using System;
using System.Collections.Generic;
using TALoaders;

namespace TALoaders.Tests
{
    using NUnit.Framework;

    [TestFixture]
    class TestYahooDownloader
    {
        private YahooDownloader loaderM = new YahooDownloader(); 
        
        [Test]
        [Category("DataCollection")]
        public void getHistoricalData()
        {
            // Test AdjClose
            SortedList<DateTime, double> adjClose = loaderM.getHistoricalPrices("^OMX", new DateTime(2010, 1, 5), new DateTime(2010, 2, 5), QuoteType.AdjClose);
            Assert.AreEqual(973.44, adjClose.Values[2], "Testing Adjusted Close");
            
            // Test Low
            SortedList<DateTime, double> lows = loaderM.getHistoricalPrices("^OMX", new DateTime(2010, 1, 5), new DateTime(2010, 2, 5), QuoteType.Low);
            double totalLow = 0;
            foreach (double dailyLow in lows.Values)
                totalLow += dailyLow;
            Assert.AreEqual(21963.97, totalLow, "Testing LOW");

            // Test Open
            SortedList<DateTime, double> open = loaderM.getHistoricalPrices("^OMX", new DateTime(2010, 1, 15), new DateTime(2010, 2, 5), QuoteType.Open);
            Assert.AreEqual(open.Values[1], 970.41, "Testing OPEN");
        }

        [Test]
        [Category("DataCollection")]
        public void getHistoricalDataAllQuoteTypes()
        {
            string ticker = "USO";
            SortedList<DateTime, Quote> quotes = loaderM.getHistoricalPrices(ticker, new DateTime(2010, 1, 19), new DateTime(2010, 1, 22));
            DateTime d = new DateTime(2010, 1, 20);
            Quote quote = quotes[d];
            Assert.AreEqual(38.23, quote.getValue(QuoteType.Open), "OPEN");
            Assert.AreEqual(38.35, quote.getValue(QuoteType.High), "HIGH");
            Assert.AreEqual(37.88, quote.getValue(QuoteType.Low), "LOW");
            Assert.AreEqual(37.89, quote.getValue(QuoteType.Close), "CLOSE");
            Assert.AreEqual(11439300, quote.getValue(QuoteType.Volume), "VOLUME");
            Assert.AreEqual(37.89, quote.getValue(QuoteType.AdjClose), "AdjClose");
            Assert.AreEqual(0.5 * (38.35 + 37.88), quote.getValue(QuoteType.AvgHL), "(H+L)/2");
            Assert.AreEqual((38.35 + 37.88 + 37.89) / 3.0, quote.getValue(QuoteType.AvgHLC), "(H+L+C)/3");
            
            SortedList<DateTime, double> avgHLC = loaderM.getHistoricalPrices(ticker, new DateTime(2010, 1, 19), new DateTime(2010, 1, 23), QuoteType.AvgHLC);
            Assert.AreEqual(38.04, avgHLC[d], "get AvgHLC QuoteType");
        }


        [Test]
        [Category("DataCollection")]
        public void getLastPrice()
        {
            string ticker = "^FTSE";
            DateTime start = DateTime.Now;
            start = start.AddDays(-5);

            SortedList<DateTime, double> history = loaderM.getHistoricalPrices(ticker, start, DateTime.Now, QuoteType.Close);
            double lastHistory = history.Values[history.Count-1];
            string timeStamp;
            double lastPrice = loaderM.getLastPrice(ticker, out timeStamp);
            Assert.Less(Math.Abs(lastHistory - lastPrice) / lastPrice, 0.2); // Assume that moves less than 20% in a day
        }

        [Test]
        [Category("DataCollection")]
        public void getHistoricalDataTestLoader()
        {
            TestDownloader tLoader = new TestDownloader();
            SortedList<DateTime, Quote> quotes = tLoader.getHistoricalPrices("TEST", new DateTime(2010, 1, 19), new DateTime(2010, 1, 23));
            DateTime d = new DateTime(2010, 1, 20);
            Quote quote = quotes[d];
            Assert.AreEqual(980.63, quote.getValue(QuoteType.Open), "OPEN");
            Assert.AreEqual(1010.0489, quote.getValue(QuoteType.High), "HIGH");
            Assert.AreEqual(980.63, quote.getValue(QuoteType.Low), "LOW");
            Assert.AreEqual(980.63, quote.getValue(QuoteType.Close), "CLOSE");
            Assert.AreEqual(100, quote.getValue(QuoteType.Volume), "VOLUME");
            Assert.AreEqual(980.63, quote.getValue(QuoteType.AdjClose), "AdjClose");
            Assert.AreEqual(0.5 * (1010.0489 + 980.63), quote.getValue(QuoteType.AvgHL), "(H+L)/2");
            Assert.AreEqual((1010.0489 + 980.63 + 980.63) / 3.0, quote.getValue(QuoteType.AvgHLC), "(H+L+C)/3");

            SortedList<DateTime, double> avgHL = tLoader.getHistoricalPrices("TEST", new DateTime(2010, 1, 19), new DateTime(2010, 1, 23), QuoteType.AvgHL);
            Assert.AreEqual(0.5 * (1010.0489 + 980.63), avgHL[d], "get AvgHL QuoteType");
        }
    }
}
